package bhz.netty_me.first;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;

import java.io.UnsupportedEncodingException;

/*
* 第一个TCP服务器
* */
public class TcpServer {

 public static void main(String[] args) throws InterruptedException {
   EventLoopGroup bossGroup = new NioEventLoopGroup();
   EventLoopGroup workerGroup = new NioEventLoopGroup();
   try {
     ServerBootstrap b = new ServerBootstrap();
     b.group(bossGroup, workerGroup)
         .channel(NioServerSocketChannel.class)
         .childHandler(new ChannelInitializer<SocketChannel>() {
           @Override
           public void initChannel(SocketChannel ch)
               throws Exception {
             ch.pipeline().addLast(new TcpServerHandler());
           }
         });
     ChannelFuture f = b.bind(8080).sync();
     f.channel().closeFuture().sync();
   } finally {
     workerGroup.shutdownGracefully();
     bossGroup.shutdownGracefully();
   }
 }

}

class TcpServerHandler extends ChannelHandlerAdapter {

 // 接收到新的数据
 @Override
 public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {
   try {
     // 接收客户端的数据
     ByteBuf in = (ByteBuf) msg;
     System.out.println("channelRead:" + in.toString(CharsetUtil.UTF_8));

     // 发送到客户端
     byte[] responseByteArray = "你好".getBytes("UTF-8");
     ByteBuf out = ctx.alloc().buffer(responseByteArray.length);
     out.writeBytes(responseByteArray);
     ctx.writeAndFlush(out);
   } finally {
     ReferenceCountUtil.release(msg);
   }
 }

 @Override
 public void channelActive(ChannelHandlerContext ctx) {
   System.out.println("客户端进入...");
 }

 @Override
 public void channelInactive(ChannelHandlerContext ctx){
   System.out.println("客户端退出...");
 }

 @Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
   cause.printStackTrace();
   ctx.close();
 }
}